/**
 * 公式：计算高差
 * @param h1 第1基塔的高差
 * @param h2 第2基塔的高差
 * @returns 高差
 */
export const calcH = (h1: number, h2: number) => {
  return h2 - h1
}

/**
 * 公式：计算高差角
 * @param h 高差
 * @param btSpan 档距
 * @returns 高差角
 */
export const calcAngle = (h: number, btSpan: number) => {
  return Math.atan(h / btSpan)
}

/**
 * 公式：控制点水平张力
 * @param w 自重比载
 * @param x 控制点x
 * @param btSpan 档距
 * @param h1 前一基塔高差y
 * @param y 控制点x
 * @param angle 高差角
 * @returns 控制点水平张力
 */
export const calcHi = (w: number, x: number, btSpan: number, h1: number, y: number, angle: number) => {
  // W牵*X*(li-X)/2/(($C8-Y)*COS(Ψ)+X*SIN(Ψ))
  return (w * x * (btSpan - x)) / 2 / ((h1 - y) * Math.cos(angle) + x * Math.sin(angle))
}

/**
 * 公式：控制点的平视弧垂
 * @param w 自重比载
 * @param btSpan 档距
 * @param Hi 水平张力
 * @param angle 高差角
 * @param h 高差
 * @returns 平视弧垂
 */
export const calcFi = (w: number, btSpan: number, Hi: number, angle: number, h: number) => {
  // li^2*W牵/8/Hi/COS(Ψ)*a^2
  // a = 1+2*Hi*h*COS(Ψ)/li^2/W牵
  const a = 1 + (2 * Hi * h * Math.cos(angle)) / Math.pow(btSpan, 2) / w
  return ((Math.pow(btSpan, 2) * w) / 8 / Hi / Math.cos(angle)) * Math.pow(a, 2)
}

/**
 * 公式：计算出口张力
 * @param w 自重比载
 * @param e 摩阻系数
 * @param i 顺序号
 * @param eh 中间变量
 * @param Hi 水平张力
 * @param Fi 平视弧垂
 * @returns 出口张力
 */
export const calcTi = (w: number, e: number, i: number, eh: number, Hi: number, Fi: number) => {
  // e^(1-i)*Hi-W牵*(eh-e^(1-i)*fi)
  return Math.pow(e, -i) * Hi - w * (eh - Math.pow(e, -i) * Fi)
}

/**
 * 计算轴向张力
 * @param w 自重比载
 * @param ph 前一基塔的轴向张力
 * @param h 高差
 * @param e 摩阻系数
 * @returns 轴向张力
 */
export const calcPh = (w: number, ph: number, h: number, e: number) => {
  // (N6+W牵*(F7))*e
  return (ph + w * h) * e
}

/**
 * 计算任意点Y的坐标
 * @param w 自重比载
 * @param y0 前一基铁塔的高程
 * @param h 高差
 * @param btspan 档距
 * @param x x的坐标
 * @param hi 水平张力
 * @returns
 */
export const calcCurveY = (w: number, y0: number, h: number, btspan: number, x: number, hi: number) => {
  // y = Y0 + H - (L + x) * H / L + w * x * (L + x) / 2 / Hi / L * (H ^ 2 + L ^ 2) ^ 0.5 反向计算
  // y = Y0 + x * H / L - w * x * (L - x) / 2 / Hi / L * (H ^ 2 + L ^ 2) ^ 0.5 正向计算
  const a = y0 + (x * h) / btspan
  const b = (w * x * (btspan - x)) / 2 / hi / btspan
  const c = Math.pow(h, 2) + Math.pow(btspan, 2)
  return a - b * Math.pow(c, 0.5)
}
